Skip to content

usb: dwc3: gadget: don't error on dequeue of a completed request - #22

Open
munzzyy wants to merge 202 commits into
flipperdevices:flipper-develfrom
munzzyy:usb-dwc3-gadget-don-t-error-on-dequeue-of-an-alr
Open

usb: dwc3: gadget: don't error on dequeue of a completed request#22
munzzyy wants to merge 202 commits into
flipperdevices:flipper-develfrom
munzzyy:usb-dwc3-gadget-don-t-error-on-dequeue-of-an-alr

Conversation

@munzzyy

@munzzyy munzzyy commented Aug 1, 2026

Copy link
Copy Markdown

Closes #20.

Reshaped to option 2 from the issue rather than the fork-local carry, so it can go to linux-usb as-is.

The 2022 thread ended on Thinh's point that functionfs_unbind() only runs after a disconnect, and that soft-disconnect already stalls and gives back any pending control transfer. That's correct, and it's what makes this safe to fix in dequeue: by the time f_fs dequeues ep0req the request has already completed, so finding it on none of the three lists is the expected state rather than a fault.

The patch keys off dwc3's own per-request status instead of usb_request::status:

  • dwc3_gadget_ep_alloc_request() sets DWC3_REQUEST_STATUS_UNKNOWN
  • __dwc3_gadget_ep_queue() and __dwc3_gadget_ep0_queue() set DWC3_REQUEST_STATUS_QUEUED
  • dwc3_gadget_giveback() sets DWC3_REQUEST_STATUS_COMPLETED

Reaching the end of dequeue with COMPLETED therefore means the request was queued to this endpoint and has finished. Anything else means it was never queued here, or the driver lost track of it, and those keep the dev_err and the -EINVAL.

That is the difference from the cdnsp fix, 34f08eb, which returns 0 whenever usb_request::status != -EINPROGRESS. That field is zero straight out of allocation, so cdnsp also quietly accepts a request that was never queued anywhere. Thinh's ask on the 2022 patch was to validate the request and return an error when it isn't a valid one to dequeue, and keying off the driver's own status keeps that property.

Verified here: gadget.o builds clean for arm64, sparse (C=1) reports nothing, checkpatch --strict is 0/0/0. The observable effect, the log line gone at gadget teardown, still needs your hardware.

Happy to send it to linux-usb once you're good with the shape.

cristicc and others added 30 commits July 28, 2026 13:07
…hannel

The DisplayPort AUX channel gets initialized and registered during
dw_dp_bind(), but it is never unregistered, which may lead to resource
leaks and/or use-after-free.

Add the missing dw_dp_unbind() function to allow the users of the
library to handle the required cleanup, i.e. unregister the AUX adapter.

Fixes: 86eecc3 ("drm/bridge: synopsys: Add DW DPTX Controller support library")
Signed-off-by: Cristian Ciocaltea <cristian.ciocaltea@collabora.com>
Link: https://lore.kernel.org/r/20260327-drm-rk-fixes-v3-1-fd2e6900c08c@collabora.com
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Also log to normal dmesg to assist debugging hard reset issues.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Also log to normal dmesg to assist debugging hard reset issues.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Add a new DIV_ROUND_UP helper, which cannot overflow when
big numbers are being used.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
The clock framework handles clock rates as "unsigned long", so u32 on
32-bit architectures and u64 on 64-bit architectures.

The current code casts the dividend to u64 on 32-bit to avoid a
potential overflow. For example DIV_ROUND_UP(3000000000, 1500000000)
= (3.0G + 1.5G - 1) / 1.5G = = OVERFLOW / 1.5G, which has been
introduced in commit 9556f9d ("clk: divider: handle integer overflow
when dividing large clock rates").

On 64 bit platforms this masks the divisor, so that only the lower
32 bit are used. Thus requesting a frequency >= 4.3GHz results
in incorrect values. For example requesting 4300000000 (4.3 GHz) will
effectively request ca. 5 MHz. Requesting clk_round_rate(clk, ULONG_MAX)
is a bit of a special case, since that still returns correct values as
long as the parent clock is below 8.5 GHz.

Fix this by switching to DIV_ROUND_UP_NO_OVERFLOW, which cannot
overflow. This avoids any requirements on the arguments (except
that divisor should not be 0 obviously).

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Replace the open coded abs_diff() with the existing helper function.

Suggested-by: Andy Shevchenko <andriy.shevchenko@intel.com>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Add rfkill support for bluetooth. Bluetooth support itself is still
missing, but this ensures bluetooth can be powered off properly.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Also describe wake signal PCIe pinmux for the onboard LAN card.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
This drops to hs200 mode and 150Mhz as this is actually stable across
eMMC modules. There exist some that are incompatible at higher rates
with the rk3588 and to avoid your filesystem corrupting due to IO
errors, be more conservative and reduce the max. speed.

Signed-off-by: Carsten Haitzler <raster@rasterman.com>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
When I converted rk808 to device managed resources I converted the rk808
specific pm_power_off handler to devm_register_sys_off_handler() using
SYS_OFF_MODE_POWER_OFF_PREPARE, which is allowed to sleep. I did this
because the driver's poweroff function makes use of regmap and the backend
of that might sleep.

But the PMIC poweroff function will kill off the board power and the
kernel does some extra steps after the prepare handler. Thus the prepare
handler should not be used for the PMIC's poweroff routine. Instead the
normal SYS_OFF_MODE_POWER_OFF phase should be used. The old pm_power_off
method is also being called from there, so this would have been a
cleaner conversion anyways.

But it still makes sense to investigate the sleep handling and check
if there are any issues. Apparently the Rockchip and Meson I2C drivers
(the only platforms using the PMICs handled by this driver) both have
support for atomic transfers and thus may be called from the atomic
poweroff context.

Things are different on the SPI side. That is so far only used by rk806
and that one is only used by Rockchip RK3588. Unfortunately the Rockchip
SPI driver does not support atomic transfers. That means this change will
introduce an error splash directly before doing the final power off on all
upstream supported RK3588 boards:

[   13.761353] ------------[ cut here ]------------
[   13.761764] Voluntary context switch within RCU read-side critical section!
[   13.761776] WARNING: CPU: 0 PID: 1 at kernel/rcu/tree_plugin.h:330 rcu_note_context_switch+0x3ac/0x404
[   13.763219] Modules linked in:
[   13.763498] CPU: 0 UID: 0 PID: 1 Comm: systemd-shutdow Not tainted 6.10.0-12284-g2818a9a19514 #1499
[   13.764297] Hardware name: Rockchip RK3588 EVB1 V10 Board (DT)
[   13.764812] pstate: 604000c9 (nZCv daIF +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[   13.765427] pc : rcu_note_context_switch+0x3ac/0x404
[   13.765871] lr : rcu_note_context_switch+0x3ac/0x404
[   13.766314] sp : ffff800084f4b5b0
[   13.766609] x29: ffff800084f4b5b0 x28: ffff00040139b800 x27: 00007dfb4439ae80
[   13.767245] x26: ffff00040139bc80 x25: 0000000000000000 x24: ffff800082118470
[   13.767880] x23: 0000000000000000 x22: ffff000400300000 x21: ffff000400300000
[   13.768515] x20: ffff800083a9d600 x19: ffff0004fee48600 x18: fffffffffffed448
[   13.769151] x17: 000000040044ffff x16: 005000f2b5503510 x15: 0000000000000048
[   13.769787] x14: fffffffffffed490 x13: ffff80008473b3c0 x12: 0000000000000900
[   13.770421] x11: 0000000000000300 x10: ffff800084797bc0 x9 : ffff80008473b3c0
[   13.771057] x8 : 00000000ffffefff x7 : ffff8000847933c0 x6 : 0000000000000300
[   13.771692] x5 : 0000000000000301 x4 : 40000000fffff300 x3 : 0000000000000000
[   13.772328] x2 : 0000000000000000 x1 : 0000000000000000 x0 : ffff000400300000
[   13.772964] Call trace:
[   13.773184]  rcu_note_context_switch+0x3ac/0x404
[   13.773598]  __schedule+0x94/0xb0c
[   13.773907]  schedule+0x34/0x104
[   13.774198]  schedule_timeout+0x84/0xfc
[   13.774544]  wait_for_completion_timeout+0x78/0x14c
[   13.774980]  spi_transfer_one_message+0x588/0x690
[   13.775403]  __spi_pump_transfer_message+0x19c/0x4ec
[   13.775846]  __spi_sync+0x2a8/0x3c4
[   13.776161]  spi_write_then_read+0x120/0x208
[   13.776543]  rk806_spi_bus_read+0x54/0x88
[   13.776905]  _regmap_raw_read+0xec/0x16c
[   13.777257]  _regmap_bus_read+0x44/0x7c
[   13.777601]  _regmap_read+0x60/0xd8
[   13.777915]  _regmap_update_bits+0xf4/0x13c
[   13.778289]  regmap_update_bits_base+0x64/0x98
[   13.778686]  rk808_power_off+0x70/0xfc
[   13.779024]  sys_off_notify+0x40/0x6c
[   13.779356]  atomic_notifier_call_chain+0x60/0x90
[   13.779776]  do_kernel_power_off+0x54/0x6c
[   13.780146]  machine_power_off+0x18/0x24
[   13.780499]  kernel_power_off+0x70/0x7c
[   13.780845]  __do_sys_reboot+0x210/0x270
[   13.781198]  __arm64_sys_reboot+0x24/0x30
[   13.781558]  invoke_syscall+0x48/0x10c
[   13.781897]  el0_svc_common+0x3c/0xe8
[   13.782228]  do_el0_svc+0x20/0x2c
[   13.782528]  el0_svc+0x34/0xd8
[   13.782806]  el0t_64_sync_handler+0x120/0x12c
[   13.783197]  el0t_64_sync+0x190/0x194
[   13.783527] ---[ end trace 0000000000000000 ]---

The board will shutdown nevertheless, since this also re-enables
interrupts. A proper fix for this requires changes to the core SPI
subsystem and will be done as a follow-up series.

Note, that this patch also fixes a problem for the Asus C201. Without
the function being registered as a proper shutdown handler the syscall
for poweroff exits early and does not even call the shutdown prepare
handler. This in turn means the system can no longer poweroff properly
since my original change.

Fixes: 4fec8a5 ("mfd: rk808: Convert to device managed resources")
Cc: stable@vger.kernel.org
Reported-by: Urja <urja@urja.dev>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Add the documentation for VOP2 video ports reset clocks.
One reset can be set per video port.

Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
Signed-off-by: Detlev Casanova <detlev.casanova@collabora.com>
At the end of initialization, each VP clock needs to be reset before
they can be used.

Failing to do so can put the VOP in an undefined state where the
generated HDMI signal is either lost or not matching the selected mode.

This issue can be reproduced by switching modes multiple times.
Depending on the setup, after about 10 mode switches, the signal will be
lost and the value in register 0x890 (VSYNCWIDTH + VFRONT) will take the value
`0x0000018c`.
That makes VSYNCWIDTH=0, which is wrong.

Adding the clock resets after the VOP configuration fixes the issue.

Signed-off-by: Detlev Casanova <detlev.casanova@collabora.com>
This adds the needed clock resets for all rk3588(s) based SOCs.

Signed-off-by: Detlev Casanova <detlev.casanova@collabora.com>
The RK3588 EVB1 comes with a W552793DBA-V10 Touchscreen/Display
combination. It contains a Wanchanglong W552793BAA panel and a
Goodix GT1158 touchscreen. This adds the DT description of it.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
A previous from Detlev Casanova adds reset handling for the
video ports. This also resets the AHB and AXI interface when
the system binds the VOP2 controller.

This fixes issues when the bootloader (or a previously running
kernel when using kexec) left the VOP2 initialized to some degree.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Fix the USB-C connector description, so that it follows the binding:

port@0 is the high-speed lanes
port@1 is the super-speed lanes
port@2 is the SBU lanes

Right now the high-speed and super-speed links are swapped and
for the high-speed lanes the link points to the controller instead
of the PHY. I'm still investigating if this should be changed.

This also updates the port naming, so that it describes the hardware
instead of how the drivers are using the information. These are
effectively the same, but the DT should describe hardware and not
software.

Fixes: b37146b ("arm64: dts: rockchip: add USB3 to rk3588-evb1")
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Any camera related IP of the RK3588 is not yet supported and the cameras
must be handled via overlays anyways, but it is sensible to expose the
related I2C interfaces by default. This allows using i2cdetect to
investigate anything connected to the CSI connectors right now. Since
the Rockchip I2C driver implements proper power management there are no
disadvantages, if nothing is connected to the port.

Note, that the second CSI port's I2C in the Rock 5B+ and Rock 5T reuse
I2C4, which is already used by fusb302 and thus already enabled.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
With USB type C connectors, the vbus detect pin of the OTG controller
attached to it is pulled high by a USB Type C controller chip such as
the fusb302. This means USB enumeration on Type-C ports never works, as
the vbus is always seen as high.

Rockchip added some GRF register flags to deal with this situation. The
RK3576 TRM calls these "soft_vbusvalid_bvalid" (con0 bit index 15) and
"soft_vbusvalid_bvalid_sel" (con0 bit index 14).

Downstream introduces a new vendor property which tells the USB 2 PHY
that it's connected to a type C port, but we can do better. Since in
such an arrangement, we'll have an OF graph connection from the USB
controller to the USB connector anyway, we can walk said OF graph and
check the connector's compatible to determine this without adding any
further vendor properties.

Do keep in mind that the usbdp PHY driver seemingly fiddles with these
register fields as well, but what it does doesn't appear to be enough
for us to get working USB enumeration, presumably because the whole
vbus_attach logic needs to be adjusted as well either way.

Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
Link: https://lore.kernel.org/r/20250610-rk3576-sige5-usb-v4-1-7e7f779619c1@collabora.com
Signed-off-by: Sebastian Reichel <sre@kernel.org>
adc-keys, unlike gpio-keys, does not allow linux,input-type as a valid
property. This makes it impossible to model devices that have ADC inputs
that should generate switch events.

Add the property to the binding with the same default as gpio-keys.

Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
Link: https://lore.kernel.org/r/20250630-rock4d-audio-v1-1-0b3c8e8fda9c@collabora.com
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Instead of doing something like what gpio-keys is doing, adc-keys
hardcodes that all keycodes must be of type EV_KEY.

This limits the usefulness of adc-keys, and overcomplicates the code
with manual bit-setting logic.

Instead, refactor the code to read the linux,input-type fwnode property,
and get rid of the custom bit setting logic, replacing it with
input_set_capability instead. input_report_key is replaced with
input_event, which allows us to explicitly pass the type.

Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
Link: https://lore.kernel.org/r/20250630-rock4d-audio-v1-2-0b3c8e8fda9c@collabora.com
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
The RADXA ROCK 4D, like many other Rockchip-based boards, uses an ES8388
analog audio codec. On the production version of the board, the codec's
LOUT1 and ROUT1 pins are tied to the headphone jack, whereas pins LOUT2
and ROUT2 lead to a non-populated speaker amplifier that itself leads to
a non-populated speaker jack. The schematic is still haunted by the
ghosts of those symbols, but it clearly marks them as "NC".

The 3.5mm TRRS jack has its microphone ring (and ground ring) wired to
the codec's LINPUT1 and RINPUT1 pins for differential signalling.

Furthermore, it uses the SoCs ADC to detect whether the inserted cable
is of headphones (i.e., no microphone), or a headset (i.e., with
microphone). The way this is done is that the ADC input taps the output
of a 100K/100K resistor divider that divides the microphone ring pin
that's pulled up to 3.3V.

There is no ADC level difference between a completely empty jack and one
with a set of headphones (i.e., ones that don't have a microphone)
connected. Consequently headphone insertion detection isn't something
that can be done.

Add the necessary codec and audio card nodes. The non-populated parts,
i.e. LOUT2 and ROUT2, are not modeled at all, as they are not present on
the hardware.

Also, add an adc-keys node for the headset detection, which uses an
input type of EV_SW with the SW_MICROPHONE_INSERT keycode. Below the
220mV pressed voltage level of our SW_MICROPHONE_INSERT switch, we also
define a button that emits a KEY_RESERVED code, which is there to model
this part of the voltage range as not just being extra legroom for the
button above it, but actually a state that is encountered in the real
world, and should be recognised as a valid state for the ADC range to be
in so that no "closer" ADC button is chosen.

Signed-off-by: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
Link: https://lore.kernel.org/r/20250630-rock4d-audio-v1-3-0b3c8e8fda9c@collabora.com
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
On Radxa ROCK 4D boards we are seeing some issues with PHY detection and
stability (e.g. link loss or not capable of transceiving packages) after
new board revisions switched from a dedicated crystal to providing the
25 MHz PHY input clock from the SoC instead.

This board is using a RTL8211F PHY, which is connected to an always-on
regulator. Unfortunately the datasheet does not explicitly mention the
power-up sequence regarding the clock, but it seems to assume that the
clock is always-on (i.e. dedicated crystal).

By doing an explicit reset after enabling the clock, the issue on the
boards could no longer be observed.

Note, that the RK3576 SoC used by the ROCK 4D board does not yet
support system level PM, so the resume path has not been tested.

Cc: stable@vger.kernel.org
Fixes: 7300c9b ("net: phy: realtek: Add optional external PHY clock")
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
According to the Ethernet controller device tree binding "rgmii-id"
means, that the PCB does not have extra long lines to add the required
delays. This is indeed the case for the ROCK 4D.

The problem is, that the Rockchip MAC Linux driver interprets the
interface type differently and abuses the information to configure
RX and TX delays in the MAC using (vendor) properties 'rx_delay' and
'tx_delay'.

When Detlev Casanova upstreamed the ROCK 4D device tree, he used the
correct description for the board ("rgmii-id"). This results in no delays
being configured in the MAC. At the same time the PHY will provide
some delays.

This works to some degree, but is not a stable configuration. All five
ROCK 4D production boards, which have recently been added to the Collabora
LAVA lab for CI purposes have trouble with data not getting through
after a connection has been established.

Using the same delay setup as the vendor device tree fixes the
functionality (at the cost of not properly following the DT binding).
As we cannot fix the driver behavior for RK3576 (some other boards
already depend on this), let's update the ROCK 4D DT instead.

Cc: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Before the Rockchip PCIe driver has been switched over to the
FIELD_PREP_WM16 macro, PCIE_CLIENT_ENABLE_LTSSM and PCIE_CLIENT_DISABLE_LTSSM
were setting bits with a mask of 0xc = 0b1100, which means BIT 2 and BIT 3.
After the conversion it only sets bit 2, with bit 3 being handled by a
separate define named PCIE_CLIENT_LD_RQ_RST_GRT. Apparently the
conversion missed to make use of this new macros resulting in the third
bit not being set.

Fixes: 30e9195 ("PCI: dw-rockchip: Switch to FIELD_PREP_WM16 macro")
Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
This reverts c930b10 ("PCI: dw-rockchip: Simplify regulator setup with
devm_regulator_get_enable_optional()"), which nicely cleaned up the code.

The vpcie3v3 regulator handle is needed to disable the regulator during
system suspend (to be added in its own patch).

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
By moving devm_phy_get() to the probe routine, rockchip_pcie_phy_init()
can be used to re-initialize the PCIe PHY, which is for example needed
after a system suspend/resume cycle.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Remove code duplication and improve readability by introducing a new
function to setup the enhanced LTSSM mode.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Remove code duplication and improve readability by introducing a new
function to setup the controller mode.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Remove code duplication and improve readability by introducing a new
function to setup the DLL indicator.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Prepare Rockchip PCIe controller for system suspend support by
adding the PME turn off operation.

Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com>
alchark and others added 23 commits July 28, 2026 13:15
Flipper One has a haptic LRA (linear resonant actuator) exposed via its
MCU interconnect interface.

Add a driver to expose the haptic actuator as a force feedback device.

Signed-off-by: Alexey Charkov <alchark@flipper.net>
Flipper One is a handheld multi-tool device with an integrated MCU that
exposes USB Type-C controller functionality among other things, following
the UCSI specification. Add a driver for it.

Signed-off-by: Alexey Charkov <alchark@flipper.net>
Reparent dclk_vp{0,1}_src from GPLL to VPLL on Rockchip RK3576. VPLL is a
programmable PLL with no other consumers, allowing the CCF to synthesize
accurate pixel clocks for the two display outputs with arbitrary modes,
as long as only one of them is active at a time (or using the HDMI PHY
as the clock source, which works for HDMI modes up to 4K@60Hz).

This gives much greater flexibility for display modes as compared to the
boot-time default of using GPLL, which is effectively fixed at 1188 MHz
due to a large number of system components depending on it and making
runtime rate changes unrealistic.

Signed-off-by: Alexey Charkov <alchark@flipper.net>
According to the TRM, the fractional PLL coefficient should be divided by
65536 rather than 65535 to obtain the output rate.

Fix the denominator and add a comment with the TRM provided clock formulae
for future reference.

See RK3576 TRM Part 1 V1.2 section 2.13.1.4 Setting Guide on P, M, S and K
or equivalently RK3588 TRM part 1 V1.0 section 2.17.1.4 Setting Guide on P,
M, S and K.

Fractional PLL rates don't seem to be used by any current mainline
consumers, so this is purely a correctness fix. It will also be important
to properly support DisplayPort output going forward, as the video output
controller derives its pixel clock from system PLLs with no dedicated PHY
PLL option for DP unlike HDMI, and some display modes are only achievable
with fractional PLL rates.

Fixes: 8f65944 ("clk: rockchip: add pll type for RK3588")
Signed-off-by: Alexey Charkov <alchark@flipper.net>
…omplement

When the PLL rates table was first committed for RK3588 (and later reused
for RK3576), the fractional PLL coefficient was defined as an unsigned
value, while the TRM clearly states that it is a two's complement 16-bit
value.

Treating the fractional PLL coefficient as unsigned in rate recalculation
results in a kernel-visible rate which deviates from what the hardware
actually generates by Fin / (p * 2^s), or 2 MHz for the two affected table
entries.

Rockchip's downstream kernel later revised the fractional PLL code [1] to
account for the two's complement nature of the coefficient, but that
change wasn't upstreamed.

Change the PLL table definition to use two's complement for the
fractional coefficient and update its users accordingly.

Note that a negative fractional coefficient is meant to be subtracted from
the next larger integer multiplier, so the m values in the table are
also adjusted accordingly for the two negative-k entries.

Rockchip's downstream commit introducing the two's complement logic for k
also does unrelated tweaks to the PLL parameters which are not explained
by the switch to the two's complement, so they are not replicated here.
If any of the parameters prove to need further tweaks (e.g. for precision
or jitter) that would better be done in targeted follow-up commits.

Fractional PLL rates don't seem to be used by any current mainline
consumers, so this is purely a correctness fix. It will also be important
to properly support DisplayPort output going forward, as the video output
controller derives its pixel clock from system PLLs with no dedicated PHY
PLL option for DP unlike HDMI, and some display modes are only achievable
using fractional PLL rates.

Link: flipperdevices/rockchip-linux@7a72bc0 [1]
Fixes: f1c506d ("clk: rockchip: add clock controller for the RK3588")
Fixes: cc40f5b ("clk: rockchip: Add clock controller for the RK3576")
Signed-off-by: Alexey Charkov <alchark@flipper.net>
Add precomputed PLL parameters for the display clocks found out in the
wild which can't be cleanly derived from the existing PLL rates.

These have been computed in a semi-bruteforce way to solve for low overall
error while preferring smaller integer dividers and multipliers, and
avoiding the fractional delta-sigma K component where possible.

Signed-off-by: Alexey Charkov <alchark@flipper.net>
…rent PLL

dclk_vp{0,1}_src muxes feed the display clock for Video Ports 0 and 1.
With CLK_SET_RATE_NO_REPARENT the mux is locked to its current parent, but
without CLK_SET_RATE_PARENT rate requests stop at the integer divider and
never reach the parent PLL, making it impossible to achieve certain pixel
clock frequencies.

Add CLK_SET_RATE_PARENT so that when dclk_vp{0,1}_src is reparented to a
programmable PLL (e.g. VPLL via assigned-clock-parents), the CCF divider
can ask the PLL to retune, utilizing its fractional capabilities to
obtain the exact pixel clock.

This flag relies on reparenting the VP0-1 source clock to VPLL at DT level
to ensure no consumer calls clk_set_rate on dclk_vp{0,1} while its parent
is set to the boot-time default of GPLL, which may skew clocks for other
consumers.

Signed-off-by: Alexey Charkov <alchark@flipper.net>
Signed-off-by: Alexey Charkov <alchark@flipper.net>
MT7921U and possibly other related chips expose a different configuration
on USB 3.0 vs. USB 2.0. Current driver logic only works with the USB 2.0
configuration, while connecting the module to a USB 3.0-only bus results
in enumeration and scanning succeeding but connections silently failing.

Add a special case for Mediatek modules on SuperSpeed busses to select
the right bulk OUT endpoint (second not first) to make them work.

Signed-off-by: Alexey Charkov <alchark@flipper.net>
…pensation

Replace the hard-coded percent values with pixel margins carried in struct
rockchip_crtc_state, sourced from the standard DRM "left/right/top/bottom
margin" connector properties (struct drm_connector_tv_margins) to pave way
for HDMI overscan compensation support.

Signed-off-by: Alexey Charkov <alchark@flipper.net>
Expose the "overscan" connector property as recognized by KWin and the
likes to compensate for TV overscan cropping.

The CRTC will use the margin values derived from this overscan percentage
in its post-composition scaler to add appropriate blank margins on all
sides of the output image so that the TV doesn't eat up visible content.

Signed-off-by: Alexey Charkov <alchark@flipper.net>
The speaker amplifier can be supplied by a higher voltage than the rest of
the codec, namely up to 5V.

When the speaker supply voltage is above 3.6V, the speaker gain boost
setting should be enabled to prevent distortion on speaker and AUX pins.

Enable gain boost setting based on the reading of the VDDSPK supply
regulator's voltage.

Signed-off-by: Alexey Charkov <alchark@flipper.net>
The VDPU383 video decoder on the RK3576 comes out of power-up with its
internal H.264 deblocking-context state uninitialised. Decoding then
intermittently produces wrong pixels at the horizontal deblock edges
(luma rows 4, 12 and 13 within each 16-row macroblock row), which
propagate through the following P-frames. The corruption is
non-deterministic and its rate varies between boards (a few percent up
to ~40%); it affects H.264 only - HEVC and VP9 on the same IP are fine.

The Rockchip vendor stack (BSP/MPP) avoids this by running a one-shot
priming decode of a small canned bitstream at every decoder power-up
(rk3576_workaround_init / rk3576_workaround_run); the mainline driver
omits it. Port that priming sequence: allocate the descriptor buffer
once at probe and run the priming decode on every pm_runtime resume,
which catches every power-up. It is scoped to the VDPU383 variant and
is best-effort - a failure is logged and decoding continues.

With the priming in place, an H.264 stream that reproduced the race
decodes bit-exact against avdec_h264 across 64 consecutive runs, versus
the reproduced baseline race without it. The priming runs once per
power-up and does not affect steady-state throughput. No devicetree
change is required: the "link" register bank the priming sequence uses
is already mapped.

Signed-off-by: Simon Wright <simon@symple.nz>
Signed-off-by: Alexey Charkov <alchark@flipper.net>
…pper One

Signed-off-by: Alexey Charkov <alchark@flipper.net>
Extend the flipper-one-input driver to support the MCU software driven
buttons. While at that, refactor the code to reduce duplication.

Signed-off-by: Alexey Charkov <alchark@flipper.net>
Commit 0b31f29 ("phy: rockchip: naneng-combphy: Consolidate SSC
configuration") moved the SSC spread spectrum direction setup into the
new rk_combphy_common_cfg_ssc() helper. That helper returns early when
the 'rockchip,enable-ssc' property is absent, whereas the equivalent
RK3568_PHYREG32 direction writes previously ran unconditionally in the
per-type switch statements, independent of whether SSC modulation was
actually enabled.

As no in-tree board sets 'rockchip,enable-ssc', this changed the behavior
at least for USB3 on RK3576, which now fails to bring up the link.
USB 2.0 still enumerates, but USB 3.0 does not, and the SuperSpeed root
port floods the log every second with:

  usb usb2-port1: Cannot enable. Maybe the USB cable is bad?

This was observed on two different RK3576 devices with a CoreChips SL6341
USB 2.0/3.0 hub connected to the USB DRD controller running in host mode.

Perform the SSC direction writes for PCIe/USB3 (and SATA) before the
enable_ssc check so that they always run, as they did before the
consolidation.

Cc: stable@vger.kernel.org
Fixes: 0b31f29 ("phy: rockchip: naneng-combphy: Consolidate SSC configuration")
Signed-off-by: Alexey Charkov <alchark@flipper.net>
Add a single DT overlay that disables the display pipeline so it can be
powered down when booting to a headless "No Graphics" target: the VOP
display controller and its IOMMU, the HDMI and DP interfaces and their
PHYs, the HDMI/DP audio cards, and the rockchip-drm display-subsystem
aggregator.

The Mali GPU is deliberately left enabled: a headless system may still
drive a directly-attached panel (e.g. the Flipper One SPI panel, its own
drm/tiny device) whose userspace renders via GLES/EGL, which needs the
GPU. The GPU idles into its own power domain via runtime PM when unused,
so leaving it enabled costs practically nothing.

All disabled nodes are SoC nodes defined in rk3576.dtsi, so one overlay
applies to any RK3576 board; nodes a given board does not enable simply
stay disabled. Overlay-application tests are provided for the EVB1,
ArmSoM Sige5, NanoPi M5, Rock 4D and Flipper One boards.

With these consumers disabled, genpd powers off the PD_VO0 and PD_VO1
domains. PD_VOP is the genpd parent of PD_USB/PD_VO0/PD_VO1, so it stays
powered while USB/UFS are in use - a hardware power-tree constraint; the
VOP controller itself is left unbound and idle.

Panels driven directly over a peripheral bus rather than through the VOP
(e.g. the Flipper One SPI panel) are unaffected and keep working.

Signed-off-by: Yury Smirnov <yurymonzon@gmail.com>
The deb-pkg target installs the kernel image, System.map and config only
under /boot, unlike rpm-pkg which also places them under
/lib/modules/${KERNELRELEASE} (i.e. /usr/lib/modules on a usr-merged
system). The latter layout keeps these files available to kernel-install
even when the /boot filesystem is not distributed together with /usr.

Additionally install the image (as vmlinuz), System.map and config under
/lib/modules/${KERNELRELEASE} for non-UML architectures, mirroring the
layout produced by scripts/package/kernel.spec.

Signed-off-by: Alexey Charkov <alchark@flipper.net>
… One

Some of our boards seem to take more than 500us to ramp up the audio
regulator, which causes the audio codec to fail to initialize.

Increase the enable ramp delay to 1000us to avoid this issue. This
shouldn't be noticeable to the user anyway.

Signed-off-by: Alexey Charkov <alchark@flipper.net>
Signed-off-by: Cole Munz <Munzzyy1@proton.me>
Signed-off-by: Alexey Charkov <alchark@flipper.net>
…nodes

The RK3576 CPU nodes carry no cache properties, so cache_setup_of_node()
in the generic cacheinfo core fails with -ENOENT on the first CPU. That
error propagates out of cache_shared_cpu_map_setup(), which discards the
topology arm64 had already derived from CLIDR and prints
"cacheinfo: Unable to detect cache hierarchy for CPU 0" on every boot.

Add L1 i/d cache size, line-size and sets to all eight CPU nodes, plus
per-cluster unified L2 nodes wired up through next-level-cache. Sizes
come from the RK3576 datasheet (A72 cluster: 48KB/32KB L1 I/D, 1MB L2;
A53 cluster: 32KB/32KB L1 I/D, 512KB L2). Line size and associativity
are architecturally fixed per the Cortex-A53 and Cortex-A72 TRMs, and
the *-sets values follow as size / (line-size * ways).

Same shape as the rk3399 fix that landed upstream in rk3399-base.dtsi.
Mainline rk3576.dtsi has the identical gap.

Signed-off-by: Cole Munz <Munzzyy1@proton.me>
@munzzyy
munzzyy requested a review from a team August 1, 2026 05:53
@alchark

alchark commented Aug 1, 2026

Copy link
Copy Markdown
Collaborator

Hi @munzzyy, thanks for your patch!

We’d rather not include known non-upstreamable changes into the repository, because the goal is for the Flipper to be fully usable on unpatched kernels from kernel.org

Would appreciate if you could reshape your solution in a way that addresses the maintainer’s prior feedback.

Dequeuing a request that has already been given back logs an error and
returns -EINVAL:

  dwc3 23000000.usb: request 00000000ad92f1c4 was not queued to ep0out

f_fs hits this on every teardown. functionfs_unbind() dequeues ep0req
unconditionally before freeing it, which
commit ce405d5 ("usb: gadget: f_fs: Ensure ep0req is dequeued
before free_request") made deliberate to close a use-after-free. By then
the control transfer has long completed, so dwc3_gadget_ep_dequeue()
finds the request on none of cancelled_list, pending_list or
started_list and falls through to the error path.

Nothing is actually wrong. The request is not queued, which is what the
caller asked for, and both callers ignore the return value and free the
request straight after. The only effect is an error line in every gadget
teardown, which buries real USB errors.

dwc3 already tracks enough to tell the two cases apart.
dwc3_gadget_ep_alloc_request() sets DWC3_REQUEST_STATUS_UNKNOWN, both
__dwc3_gadget_ep_queue() and __dwc3_gadget_ep0_queue() set
DWC3_REQUEST_STATUS_QUEUED, and dwc3_gadget_giveback() sets
DWC3_REQUEST_STATUS_COMPLETED. A request that reaches the end of dequeue
with status COMPLETED was queued to this endpoint and has finished.
Anything else was never queued here, or the driver lost track of it.
Keep the error for those, and return success for a completed request.

This is narrower than the cdnsp fix for the same caller,
commit 34f08eb ("usb: cdnsp: Fixes issue with dequeuing not queued
requests"), which returns 0 whenever usb_request::status is not
-EINPROGRESS. That also swallows a request that was never queued, since
status is zero out of allocation. Going by dwc3's own request status
keeps that case an error, which is what was asked for when a separate
ep0 dequeue was proposed in 2022.

Link: https://lore.kernel.org/linux-usb/20221117054917.30104-1-quic_ugoswami@quicinc.com/
Signed-off-by: Cole Munz <Munzzyy1@proton.me>
@munzzyy
munzzyy force-pushed the usb-dwc3-gadget-don-t-error-on-dequeue-of-an-alr branch from a80e093 to cf3748b Compare August 1, 2026 06:39
@munzzyy munzzyy changed the title usb: dwc3: gadget: don't error on dequeue of an already-completed request usb: dwc3: gadget: don't error on dequeue of a completed request Aug 1, 2026
@munzzyy

munzzyy commented Aug 1, 2026

Copy link
Copy Markdown
Author

Understood, and agreed on not carrying it. Reshaped and force-pushed.

Rather than the cdnsp-style no-op, it now decides on dwc3's own request status, which separates "queued here and completed" from "never queued here". The first returns success, the second keeps the dev_err and -EINVAL. That was Thinh's actual ask on the 2022 patch, and the reason it can be answered now is his own argument in that thread: functionfs_unbind() runs after soft-disconnect, so the request is guaranteed given back by then.

Details in the updated description. arm64 build, sparse and checkpatch --strict are all clean. I'll send it to linux-usb whenever you're happy with the shape, with the ftrace from #20 as the reproducer Thinh asked for back then.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

dwc3: "request ... was not queued to ep0out" on every FunctionFS gadget teardown